package com.zl.autocode.service.autocode.impl;

import java.util.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zl.autocode.common.constant.AutocodeEnum;
import com.zl.autocode.dao.autocode.ZlTableColumnMapper;
import com.zl.autocode.dao.autocode.ZlTableMapper;
import com.zl.autocode.dto.autocode.table.ReqTableAddDTO;
import com.zl.autocode.dto.autocode.table.ReqTableDelDTO;
import com.zl.autocode.dto.autocode.table.ReqTableDetailDTO;
import com.zl.autocode.dto.autocode.table.ReqTableEditDTO;
import com.zl.autocode.dto.autocode.table.ReqTableQueryDTO;
import com.zl.autocode.dto.autocode.table.ReqTableStateDTO;
import com.zl.autocode.dto.autocode.table.ResTableAddDTO;
import com.zl.autocode.dto.autocode.table.ResTableDelDTO;
import com.zl.autocode.dto.autocode.table.ResTableDetailDTO;
import com.zl.autocode.dto.autocode.table.ResTableEditDTO;
import com.zl.autocode.dto.autocode.table.ResTableQueryDTO;
import com.zl.autocode.dto.autocode.table.ResTableStateDTO;
import com.zl.autocode.dto.autocode.table.ResTableVO2;
import com.zl.autocode.entity.autocode.ZlTable;
import com.zl.autocode.entity.autocode.ZlTableColumn;
import com.zl.autocode.entity.autocode.po.ZlTableColumnVo;
import com.zl.autocode.entity.autocode.po.ZlTableVo;
import com.zl.autocode.service.autocode.ITableService;
import com.zl.autocode.service.base.AutocodeBaseManager;
import com.zl.common.dto.ReqDTO;
import com.zl.common.dto.pagination.PageReqVO;
import com.zl.common.enums.resp.GlobalRespEnum;
import com.zl.common.exception.BizException;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;

/**
 * 数据库表信息
 * @author ZL
 */
@Service("autocodeTableService")
public class TableServiceImpl extends AutocodeBaseManager implements ITableService {

    @Autowired
    private ZlTableMapper tableMapper;
    @Autowired
    private ZlTableColumnMapper tableColumnMapper;

    @Override
    public ResTableQueryDTO queryTableList(ReqDTO<ReqTableQueryDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableQueryDTO reqData = reqInfo.getReqData();
        PageReqVO page = pageHandle(reqInfo.getPageInfo());//处理分页数据
        ResTableQueryDTO resDTO = BeanUtil.copyProperties(page, ResTableQueryDTO.class);
        if(StringUtils.isNotBlank(reqData.getTableCode())){
            reqData.setTableCode("%"+reqData.getTableCode()+"%");
        }
        if(StringUtils.isNotBlank(reqData.getTableName())){
            reqData.setTableName("%"+reqData.getTableName()+"%");
        }
        if(StringUtils.isNotBlank(reqData.getTableTag())){
            reqData.setTableTag("%"+reqData.getTableTag()+"%");
        }
        Map<String,Object> paramMap = BeanUtil.beanToMap(reqData,false,true);
        
        Page<Object> pageHp = PageHelper.startPage(page.getPage(), page.getLimit(),page.getSortorder());
        List<ZlTableVo> list = tableMapper.selectListPage(paramMap);
        resDTO.setData(BeanUtil.copyToList(list, ResTableVO2.class));
        resDTO.setCount(pageHp.getTotal());
        
        return resDTO;
    }
    
    @Override
    public ResTableDetailDTO queryTableDetail(ReqDTO<ReqTableDetailDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableDetailDTO reqData = reqInfo.getReqData();
        ResTableDetailDTO res = new ResTableDetailDTO();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqData);
        ZlTable view = tableMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(view, res);
        return res;
    }
    
    @Override
    public ResTableAddDTO insertTableInfo(ReqDTO<ReqTableAddDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableAddDTO reqData = reqInfo.getReqData();
        ResTableAddDTO res = new ResTableAddDTO();
        Date time = getSystemTime().getDate();
        
        ZlTable record = new ZlTable();
        BeanUtil.copyProperties(reqData, record);
        initCreateInfo(record, reqInfo, time);
        record.setTableCode(record.getTableCode().toLowerCase());
        record.setTableId(IdUtil.simpleUUID());
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("tableId",record.getTableId());
        //检查主键是否冲突
        if(tableMapper.countExistKey(paramMap)>0){
            throw new BizException(GlobalRespEnum.DUPLICATE_PRIMARY_KEY);
        }
        
        tableMapper.insertSelective(record);
        
        ZlTable keyInfo = tableMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResTableEditDTO updateTableInfo(ReqDTO<ReqTableEditDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableEditDTO reqData = reqInfo.getReqData();
        ResTableEditDTO res = new ResTableEditDTO();
        Date time = getSystemTime().getDate();
        
        ZlTable record = new ZlTable();
        BeanUtil.copyProperties(reqData, record);
        initUpdateInfo(record, reqInfo, time);
        record.setTableCode(record.getTableCode().toLowerCase());
        
        tableMapper.updateByPrimaryKeySelective(record);
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("tableId",record.getTableId());
        ZlTable keyInfo = tableMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResTableDelDTO deleteTableInfo(ReqDTO<ReqTableDelDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableDelDTO reqData = reqInfo.getReqData();
        ResTableDelDTO res = new ResTableDelDTO();
        Date time = getSystemTime().getDate();
        
        Map<String,Object> paramMap = BeanUtil.beanToMap(reqData);
        ZlTable record = tableMapper.selectOneByMap(paramMap);
        paramMap.put("projectId",record.getProjectId());
        paramMap.put("tableCode",record.getTableCode());
        if(tableColumnMapper.countExistKey(paramMap) > 0){
            throw new BizException(GlobalRespEnum.DELETION_NOT_ALLOWED);
        }
        
        tableMapper.deleteByMap(paramMap);
        
        return res;
    }
    
    @Override
    public ResTableStateDTO updateTableState(ReqDTO<ReqTableStateDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableStateDTO reqData = reqInfo.getReqData();
        ResTableStateDTO res = new ResTableStateDTO();
        Date time = getSystemTime().getDate();
         
        ZlTable record = new ZlTable();
        BeanUtil.copyProperties(reqData, record);
        initUpdateInfo(record, reqInfo, time);
        tableMapper.updateByPrimaryKeySelective(record);
         
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("tableId",record.getTableId());
        ZlTable keyInfo = tableMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResTableQueryDTO queryTableColumnList(ReqDTO<ReqTableQueryDTO> reqInfo) throws Exception{
        ReqTableQueryDTO reqData = reqInfo.getReqData();
        PageReqVO page = pageHandle(reqInfo.getPageInfo());//处理分页数据
        ResTableQueryDTO resDTO = new ResTableQueryDTO();
        
        if(StringUtils.isNotBlank(reqData.getTableCode())){
            reqData.setTableCode("%"+reqData.getTableCode()+"%");
        }
        if(StringUtils.isNotBlank(reqData.getTableName())){
            reqData.setTableName("%"+reqData.getTableName()+"%");
        }
        if(StringUtils.isNotBlank(reqData.getTableTag())){
            reqData.setTableTag("%"+reqData.getTableTag()+"%");
        }
        
        Map<String,Object> paramMap = BeanUtil.beanToMap(reqData,false,true);
        
        
        BeanUtil.copyProperties(page, resDTO);
        Page<Object> pageHp  = PageHelper.startPage(page.getPage(), page.getLimit(),page.getSortorder());
        
        List<ZlTableVo> list = tableMapper.selectListPage(paramMap);
        for(ZlTableVo lt: list){
            Map<String, Object> paramMap2 = new HashMap<>();
            paramMap2.put("tableCode", lt.getTableCode());
            paramMap2.put("projectId", lt.getProjectId());
            List<ZlTableColumn> columnList = tableColumnMapper.selectListByMapForSelectItem(paramMap2);
            List<ZlTableColumnVo> columnInfos = new ArrayList<>();
            if(columnList != null && columnList.size()>0){
                for(ZlTableColumn colx: columnList){
                    columnInfos.add(BeanUtil.copyProperties(colx, ZlTableColumnVo.class));
                }
                lt.setColumnInfos(columnInfos);
            }
        }
        resDTO.setData(BeanUtil.copyToList(list, ResTableVO2.class));
        resDTO.setCount(pageHp.getTotal());
        
        return resDTO;
    }
    
    @Override
    public ResTableDelDTO deleteTableAndColumn(ReqDTO<ReqTableDelDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqTableDelDTO reqData = reqInfo.getReqData();
        ResTableDelDTO res = new ResTableDelDTO();
        Date time = getSystemTime().getDate();
        
        if(StringUtils.isBlank(reqData.getTableId())){
            throw new BizException(GlobalRespEnum.MISSING_PARAMETER);
        }
        
        String[] ids = reqData.getTableId().split(",");
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("tableIds", "'"+StringUtils.join(ids,"','")+"'");
        List<ZlTable> records = tableMapper.selectSimpleListCodes(paramMap);
        for(ZlTable record:records){
            paramMap.put("projectId",record.getProjectId());
            paramMap.put("tableId",record.getTableId());
            paramMap.put("tableCode",record.getTableCode());
            
            tableMapper.deleteByMap(paramMap);
            tableColumnMapper.deleteByMap(paramMap);
        }
        return res;
    }
}